#include "lzvrollbox.h"
#include <QPen>
#include <QBrush>
#include <QDebug>

LzVRollBox::LzVRollBox(QWidget *parent) : QWidget(parent),
    m_iMinValue(0),
    m_iMaxValue(99),
    m_iStepValue(1),
    m_iCurrentValue(50),
    m_iNumberWidth(8),
    m_iDeviation(0),
    m_bAlterStringEnabled(false)
{
    m_pMoveNumToCenterAi = new QPropertyAnimation(this, "deviation");
    m_pMoveNumToCenterAi->setDuration(300);
    m_pMoveNumToCenterAi->setEasingCurve(QEasingCurve::OutQuad);

    //背景色
    m_iBackColor = QColor(255, 255, 255);
    m_iTextColor = QColor(0, 0, 0);
}

void LzVRollBox::setColor(QColor bgColor, QColor foreColor)
{
    m_iBackColor = bgColor;
    m_iTextColor = foreColor;

    repaint();
}

void LzVRollBox::setRange(int minValue, int maxValue)
{
    m_iMaxValue = maxValue;
    m_iMinValue = minValue;
    if(m_iMaxValue < m_iMinValue)
    {
        m_iMaxValue = m_iMinValue;
    }

    if(m_iCurrentValue > m_iMaxValue)
    {
        m_iCurrentValue = m_iMaxValue;
        emit currentValueChanged(m_iCurrentValue);
    }
    else if(m_iCurrentValue < m_iMinValue)
    {
        m_iCurrentValue = m_iMinValue;
        emit currentValueChanged(m_iCurrentValue);
    }

    int size = (height()-1)/m_iNumberWidth;
    int n = 1;
    int temp = m_iMaxValue;
    while(temp/=10)
    {
        n++;
    }

    this->setMinimumWidth(n*size/2+20);

    repaint();
}

void LzVRollBox::setStep(int step)
{
    m_iStepValue = step;
}

int LzVRollBox::currentValue()
{
    return m_iCurrentValue;
}

void LzVRollBox::setCurrentValue(int value)
{
    m_iCurrentValue = value;
    emit currentValueChanged(m_iCurrentValue);
}

QString LzVRollBox::currentString()
{
    if(m_bAlterStringEnabled)
    {
        return QString::number(m_iCurrentValue);
    }
    else
    {
        int index = (m_iCurrentValue-m_iMinValue)/m_iStepValue;
        return m_AlterString.at(index);
    }
}

QStringList LzVRollBox::alterString()
{
    return m_AlterString;
}

void LzVRollBox::setAlterString(const QStringList alterString)
{
    m_AlterString = alterString;
}

bool LzVRollBox::isAlterStringEnabled()
{
    return m_bAlterStringEnabled;
}

void LzVRollBox::setAlterStringEnable(bool bEnable)
{
    m_bAlterStringEnabled = bEnable;
}

void LzVRollBox::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event)

    QPainter painter;
    painter.begin(this);
    painter.setRenderHint(QPainter::Antialiasing, true);

    int iWidth = width()-1;
    int iHeight = height()-1;

    // 绘制背景色
    painter.save();
    painter.setPen(Qt::NoPen);
    painter.setBrush(QBrush(m_iBackColor));
    painter.drawRect(0,0,iWidth, iHeight);
    painter.restore();

    // 绘制间隔线
    m_iTextColor.setAlpha(120);
    painter.setPen(QPen(m_iTextColor,2));
    painter.drawLine(0, iHeight*3/8,iWidth, iHeight*3/8);
    painter.drawLine(0, iHeight*5/8,iWidth, iHeight*5/8);

    //正常状态下 数字位置为 0,1/4,1/2,3/4,1
    //绘制5个文字
    //qDebug() << "current" << m_iCurrentValue << " max" << m_iMaxValue << " min" << m_iMinValue;
    if(m_iCurrentValue-2>=m_iMinValue)
    {
        drawNumber(painter, m_iCurrentValue-2, -iHeight/2+m_iDeviation);
    }
    if(m_iCurrentValue-1>=m_iMinValue)
    {
        drawNumber(painter, m_iCurrentValue-1, -iHeight/4+m_iDeviation);
    }

    drawNumber(painter, m_iCurrentValue, m_iDeviation);

    if(m_iCurrentValue+1<=m_iMaxValue)
    {
        drawNumber(painter, m_iCurrentValue+1, iHeight/4+m_iDeviation);
    }
    if(m_iCurrentValue+2 <= m_iMaxValue)
    {
        drawNumber(painter, m_iCurrentValue+2, iHeight/2+m_iDeviation);
    }

    painter.end();
}

void LzVRollBox::mousePressEvent(QMouseEvent *event)
{
    m_pMoveNumToCenterAi->stop();
    m_iStartY = event->pos().y();
    m_bDragging = true;
}

void LzVRollBox::mouseMoveEvent(QMouseEvent *event)
{
    if(!m_bDragging)
    {
        return;
    }

    //int iWidth = (width()-1)/4;
    int iHeight = height()-1;

    //如何将当前数字拖动到了下一个数字的位置，则更新数字
    m_iDeviation = event->pos().y() - m_iStartY;
    if((m_iCurrentValue<m_iMaxValue)&&(m_iDeviation<=-iHeight/4))
    {
        m_iCurrentValue++;
        emit currentValueChanged(m_iCurrentValue);

        m_iDeviation += iHeight/4;
        m_iStartY -= iHeight/4;
    }

    if((m_iCurrentValue>m_iMinValue)&&(m_iDeviation>=iHeight/4))
    {
        m_iCurrentValue--;
        emit currentValueChanged(m_iCurrentValue);
        m_iDeviation -= iHeight/4;
        m_iStartY += iHeight/4;
    }

    if(m_iDeviation > iHeight/4)
    {
        m_iDeviation = iHeight/4;
    }
    if(m_iDeviation < -iHeight/4)
    {
        m_iDeviation = -iHeight/4;
    }

    repaint();
}

void LzVRollBox::mouseReleaseEvent(QMouseEvent *event)
{
    Q_UNUSED(event)

    if(m_bDragging)
    {
        m_bDragging = false;
    }

    moveNumberToCenter();
}

void LzVRollBox::drawNumber(QPainter &painter, int value, int deviation)
{
    int iWidth = width()-1;
    int iHeight = height()-1;

    int size = (iHeight - qAbs(deviation))/m_iNumberWidth;
    int transparency = 255 - qAbs(deviation)*510/iHeight;
    int textHeight = iHeight/2 - 3*qAbs(deviation)/4;
    int y = iHeight/2 + deviation - textHeight/2;

    if(transparency < 0)
    {
        transparency = 0;
    }

    QFont font;
    font.setPointSize(size);// setPixelSize(size);
    painter.setFont(font);
    m_iTextColor.setAlpha(transparency);
    painter.setPen(m_iTextColor);
    painter.drawText(QRectF(0,y,iWidth,textHeight),
                     Qt::AlignCenter,
                     QString::number(value));

//    qDebug() << "value:"<<value << " size:" << size << "transpatent" << transparency;
}

void LzVRollBox::setDeviation(int deviation)
{
    m_iDeviation = deviation;
    repaint();
}

int LzVRollBox::getDeviation()
{
    return  m_iDeviation;
}

void LzVRollBox::moveNumberToCenter()
{
//    qDebug() << m_iDeviation << height()/8;

    if(m_iDeviation > height()/8)
    {
        if(m_iCurrentValue > m_iMinValue)
        {
            m_iCurrentValue--;
            emit currentValueChanged(m_iCurrentValue);
            m_pMoveNumToCenterAi->setStartValue(-(height()-1)/4 + m_iDeviation);
        }
        else
        {
            m_pMoveNumToCenterAi->setStartValue(m_iDeviation);
        }
    }
    else if(m_iDeviation < -height()/8)
    {
        if(m_iCurrentValue < m_iMaxValue)
        {
            m_iCurrentValue++;
            emit currentValueChanged(m_iCurrentValue);
            m_pMoveNumToCenterAi->setStartValue(((height()-1)/4 + m_iDeviation));
        }
        else
        {
            m_pMoveNumToCenterAi->setStartValue(m_iDeviation);
        }
    }
    else
    {
        m_pMoveNumToCenterAi->setStartValue(m_iDeviation);

    }

    m_pMoveNumToCenterAi->setEndValue(0);
    m_pMoveNumToCenterAi->start();
}
